using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ImmlPad.Documents;
using ImmlPad.DocumentViews;
using ImmlPadPlugins;
using System.Threading;

namespace ImmlPad.Views
{
    /// <summary>
    /// Interaction logic for DocumentsView.xaml
    /// </summary>

    public partial class DocumentsView : System.Windows.Controls.UserControl
    {
        #region Events

        public event EventHandler<TypedEventArgs<IDocument>> CloseDocumentRequested;

        protected virtual void OnCloseDocumentRequested(TypedEventArgs<IDocument> e)
        {
            EventHandler<TypedEventArgs<IDocument>> handler = CloseDocumentRequested;

            if (handler != null)
                handler(this, e);
        }

        public event EventHandler<EventArgs> NewDocumentRequested;

        protected virtual void OnNewDocumentRequested(EventArgs e)
        {
            EventHandler<EventArgs> handler = NewDocumentRequested;

            if (handler != null)
                handler(this, e);
        }

        #endregion



        public Visibility CodenameFreedomVisibility
        {
            get { return (Visibility)GetValue(CodenameFreedomVisibilityProperty); }
            set { SetValue(CodenameFreedomVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CodenameFreedomVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CodenameFreedomVisibilityProperty =
            DependencyProperty.Register("CodenameFreedomVisibility", typeof(Visibility), typeof(DocumentsView), new UIPropertyMetadata(Visibility.Collapsed));



        public DocumentsView()
        {
            InitializeComponent();

            EventManager.RegisterClassHandler(typeof(TabItem), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnTabMouseDown), false);
            EventManager.RegisterClassHandler(typeof(TabControl), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnTabControlMouseDown), false);

            EditorInfo.ParseRequested += new EditorInfo.ParseRequestedDelegate(ImmlPadInfo_ParseRequested);

            try
            {
                if (Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\VastPark\VastPark Player v1.5\") != null)
                {
                    this.CodenameFreedomVisibility = Visibility.Visible;
                }
            }
            catch { }
        }

        #region XmlDocuments (DependencyProperty)

        /// <summary>
        /// description of XmlDocuments
        /// </summary>
        public ObservableCollection<IDocument> XmlDocuments
        {
            get { return (ObservableCollection<IDocument>)GetValue(XmlDocumentsProperty); }
            set { SetValue(XmlDocumentsProperty, value); }
        }

        /// <summary>
        /// DependencyProperty for XmlDocuments
        /// </summary>
        public static readonly DependencyProperty XmlDocumentsProperty =
            DependencyProperty.Register("XmlDocuments", typeof(ObservableCollection<IDocument>), typeof(DocumentsView), new FrameworkPropertyMetadata(new ObservableCollection<IDocument>()));

        #endregion

        #region SelectedDocument (DependencyProperty)

        /// <summary>
        /// The currently selected XmlDocument.
        /// </summary>
        public IDocument SelectedDocument
        {
            get { return (IDocument)GetValue(SelectedDocumentProperty); }
            set { SetValue(SelectedDocumentProperty, value); }
        }

        /// <summary>
        /// DependencyProperty for SelectedDocument
        /// </summary>
        public static readonly DependencyProperty SelectedDocumentProperty =
            DependencyProperty.Register("SelectedDocument", typeof(IDocument), typeof(DocumentsView),
            new FrameworkPropertyMetadata(default(IDocument), new PropertyChangedCallback(SelectedDocumentChanged)));

        /// <summary>
        /// PropertyChangedCallback for SelectedDocument
        /// </summary>
        private static void SelectedDocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is DocumentsView)
            {
                DocumentsView owner = (DocumentsView)obj;
                IDocument document = (IDocument)args.NewValue;

                ListBoxItem listBoxItem = (ListBoxItem)owner.ContentListBox.ItemContainerGenerator.ContainerFromItem(document);

                if (listBoxItem != null)
                {
                    IDocumentView v = (IDocumentView)listBoxItem.Template.FindName("PART_DocumentView", listBoxItem);
                    if (v != null)
                    {
                        owner._view = (IDocumentView)listBoxItem.Template.FindName("PART_DocumentView", listBoxItem);
                        owner.SelectedView = owner._view;
                        EditorInfo.Editor = owner.SelectedView.TextEditor;
                    }
                }

                if (document != null && document.NeedsReload)
                {                    
                    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                    {
                        //wait a little to allow the UI time to update
                        Thread.Sleep(300);

                        MessageBoxResult result = MessageBox.Show("Document was modified externally, would you like to reload?", "Document Modification Detected", MessageBoxButton.YesNo, MessageBoxImage.Question);

                        if (result == MessageBoxResult.Yes)
                        {
                            document.Reload();
                        }
                    }));
                }
            }
        }


        #endregion

        #region SelectedView (DependencyProperty)

        /// <summary>
        /// The view associated with the currently selected dcument.
        /// </summary>
        public IDocumentView SelectedView
        {
            get { return (IDocumentView)GetValue(SelectedViewProperty); }
            set { SetValue(SelectedViewProperty, value); }
        }

        /// <summary>
        /// DependencyProperty for SelectedView
        /// </summary>
        public static readonly DependencyProperty SelectedViewProperty =
            DependencyProperty.Register("SelectedView", typeof(IDocumentView), typeof(DocumentsView), new FrameworkPropertyMetadata(default(IDocumentView)));

        #endregion

        #region Event Handlers

        IDocumentView _view;

        private void DocumentViewLoaded(object sender, RoutedEventArgs e)
        {
            _view = (IDocumentView)sender;

            if (SelectedDocument == _view.Document)
            {
                SelectedView = _view;
                EditorInfo.Editor = SelectedView.TextEditor;
            }
        }

        void ImmlPadInfo_ParseRequested()
        {
            if (SelectedView != null)
            {
                SelectedView.Parse();
            }
        }

        #endregion

        private void DocumentTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                this.SelectedDocument = (IDocument)e.AddedItems[0];
            }
        }

        private void OpenContainingFolder(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start("explorer.exe", "/select," + this.SelectedDocument.FullPath);
            }
            catch
            {
                
            }
        }

        private void OpenWithPlayer_CodenameFreedom(object sender, RoutedEventArgs e)
        {
            _OpenWithPlayer(@"Software\VastPark\VastPark Player v1.5\");
        }

        private void OpenWithPlayer(object sender, RoutedEventArgs e)
        {
            _OpenWithPlayer(@"Software\VastPark\VastPark Player\");
        }

        private void _OpenWithPlayer(string regPath)
        {
            try
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath);
                string playerPath = (string)key.GetValue("InstallDir");

                key.Close();

                if (!System.IO.File.Exists(this.SelectedDocument.FullPath))
                {
                    MessageBox.Show("Please save the document before attempting to open in the Player", "Save Required", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }

                System.Diagnostics.Process.Start(playerPath, "\"" + this.SelectedDocument.FullPath + "\"");
            }
            catch
            {

            }
        }

        public void OnTabMouseDown(object sender, MouseButtonEventArgs e)
        {
            TabItem tab = sender as TabItem;
            if (e.RightButton == MouseButtonState.Pressed)
            {
                tab.IsSelected = true;
                e.Handled = true;
            }
            else if (e.MiddleButton == MouseButtonState.Pressed)
            {
                OnCloseDocumentRequested(new TypedEventArgs<IDocument>(tab.Header as IDocument));
            }
        }

        public void OnTabControlMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2 && e.LeftButton == MouseButtonState.Pressed)
            {
                OnNewDocumentRequested(EventArgs.Empty);
            }
        }

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            OnCloseDocumentRequested(new TypedEventArgs<IDocument>(this.SelectedDocument));
        }

        private void CloseAllButThis_Click(object sender, RoutedEventArgs e)
        {
            List<IDocument> documents = new List<IDocument>(this.XmlDocuments);

            foreach (IDocument document in documents)
            {
                if (document != this.SelectedDocument)
                {
                    OnCloseDocumentRequested(new TypedEventArgs<IDocument>(document));
                }
            }            
        }

        private void CloseAll_Click(object sender, RoutedEventArgs e)
        {
            List<IDocument> documents = new List<IDocument>(this.XmlDocuments);

            foreach (IDocument document in documents)
            {
                OnCloseDocumentRequested(new TypedEventArgs<IDocument>(document));
            }
        }       

        #region Public Methods


        #endregion
    }
}